using System;
using DaaseVarmer.helperClasses.HardwareInterface;
using Microsoft.SPOT;

namespace DaaseVarmer.helperClasses
{
    public class MotorShieldDriver : IDisposable
    {
        private Motorshield motorShield;
        private static MotorShieldDriver instance;


        //the motor steps is separated from the speed because the motors output might not be liniar
        //so it can be set depending on the motor, sets the motor steps from 0 to 10
        private int _motorstep;    
        private byte motorSpeed;                    //the current motor speed [0-250]
        private Motorshield.Motors selectedMotor;   // possible PWM motors M3 / M4
    
        private MotorShieldDriver()
        {
            //default values
            motorShield = new Motorshield();
            selectedMotor = Motorshield.Motors.M3;
            MotorDirection = true;
            motorSpeed = 0;
            _motorstep = 0;
        }
        public static MotorShieldDriver Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new MotorShieldDriver();
                }
                return instance;
            }
        }


        /// <summary>
        /// select witch motor to use 3-4
        /// default motor is M4
        /// you can only run PWM on M3 or M4
        /// </summary>
        public void SetMotor(int m)
        {
            switch (m)
            {
                case 3:
                    selectedMotor = Motorshield.Motors.M3;
                    break;
                case 4:
                    selectedMotor = Motorshield.Motors.M4;
                    break;
                default:
                    selectedMotor = Motorshield.Motors.M4;
                    break;

            }
        }
        
        /// <summary>
        /// sets the MotorDirection of the motor
        /// </summary>
        public bool MotorDirection { get; set; }

        /// <summary>
        /// Method sets the speed of the motor [0-10]
        /// </summary>
        /// <param name="speed">int 0-10</param>
        public int MotorStepSpeed
        {
            get { return _motorstep; }
            set
            {
                _motorstep = value;
                //the speed needs to correspond wiht the specific motor and its output 
                switch (_motorstep)
                {
                    case 0:
                        motorSpeed = 0;
                        motorShield.MotorControl(selectedMotor, motorSpeed, MotorDirection);
                        break;
                    case 1:
                        motorSpeed = 25;
                        motorShield.MotorControl(selectedMotor, motorSpeed, MotorDirection);
                        break;
                    case 2:
                        motorSpeed = 50;
                        motorShield.MotorControl(selectedMotor, motorSpeed, MotorDirection);
                        break;
                    case 3:
                        motorSpeed = 75;
                        motorShield.MotorControl(selectedMotor, motorSpeed, MotorDirection);
                        break;
                    case 4:
                        motorSpeed = 100;
                        motorShield.MotorControl(selectedMotor, motorSpeed, MotorDirection);
                        break;
                    case 5:
                        motorSpeed = 125;
                        motorShield.MotorControl(selectedMotor, motorSpeed, MotorDirection);
                        break;
                    case 6:
                        motorSpeed = 150;
                        motorShield.MotorControl(selectedMotor, motorSpeed, MotorDirection);
                        break;
                    case 7:
                        motorSpeed = 175;
                        motorShield.MotorControl(selectedMotor, motorSpeed, MotorDirection);
                        break;
                    case 8:
                        motorSpeed = 200;
                        motorShield.MotorControl(selectedMotor, motorSpeed, MotorDirection);
                        break;
                    case 9:
                        motorSpeed = 225;
                        motorShield.MotorControl(selectedMotor, motorSpeed, MotorDirection);
                        break;
                    case 10:
                        motorSpeed = 255;
                        motorShield.MotorControl(selectedMotor, motorSpeed, MotorDirection);
                        break;
                }
            }

            
        }

        /// <summary>
        /// the motor speeds up
        /// </summary>
        public void MotorGoFaster()
        {
            if (!IsMaxSpeed())
            {
                MotorStepSpeed = MotorStepSpeed + 1;
            }
        }

        /// <summary>
        /// the motor slows down
        /// </summary>
        public void MotorGoSlower()
        {
            if (!IsMinSpeed())
            {
                MotorStepSpeed = MotorStepSpeed - 1;
            }
        }

        /// <summary>
        /// checks if the motor is running at max speed
        /// </summary>
        /// <returns>bool</returns>
        public bool IsMaxSpeed()
        {
            if (motorSpeed == 255)
                return true;

            return false;
        }

        /// <summary>
        /// checks if the motor is running at min speed
        /// </summary>
        /// <returns>bool</returns>
        public bool IsMinSpeed()
        {
            if (motorSpeed == 0)
                return true;

            return false;
        }

        public void Dispose()
        {
            if (motorShield != null)
            {
                motorShield.Dispose(); 
            }  
        }

        public DaaseVarmer.helperClasses.HardwareInterface.Motorshield Motorshield
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }
    }

}
